package main

import (
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"github.com/redis/go-redis/v9"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"strings"
	"time"
	"webook/internal/repostiory"
	dao2 "webook/internal/repostiory/dao"
	"webook/internal/service"
	"webook/internal/web"
	"webook/internal/web/middleware"
	"webook/pkg/ginx/middleware/ratelimit"
)

func main() {
	//新建数据库和表 初始化数据库
	db := InitDB()
	//初始化服务器实例
	server := InitWebServe()
	//User服务 User路由初始化
	InitUser(server, db)
	server.Run(":8080")
}

func InitWebServe() *gin.Engine {
	server := gin.Default()

	//使用redis限流
	redisClient := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       1,
	})
	server.Use(ratelimit.NewBuilder(redisClient, time.Second, 100).Build())

	server.Use(cors.New(cors.Config{
		//是否允许跨域
		AllowOrigins: []string{"*"},
		AllowMethods: []string{"POST", "GET"},
		//在使用JWT的时候，因为我们使用了Authorization头来传递token，所以需要将Authorization头添加到AllowHeaders中
		AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
		//为了JWT
		ExposeHeaders: []string{"X-Jwt-Token"},
		//是否允许cookie
		AllowCredentials: true,
		//允许的域名
		AllowOriginFunc: func(origin string) bool {
			if strings.HasPrefix(origin, "http://localhost") {
				return true
			}
			return strings.Contains(origin, "your_website.com")
		},
		//允许的最大时间
		MaxAge: 12 * time.Hour,
	}))

	//TODO:seesion
	//gin的session初始化
	//store, err := redis.NewStore(16, "tcp", "localhost:6379", "", []byte("abcde"), []byte("abcde"))
	//if err != nil {
	//	panic(err)
	//}
	//
	////cookie的名字叫做mysession
	//server.Use(sessions.Sessions("mysession", store))
	////使用middleware来做登录状态鉴别
	//login := middleware.LoginMiddlewareBuilder{}
	//server.Use(login.LoginCheck())

	//使用jwt来做登录状态鉴别
	login := middleware.NewLoginMiddlewareJWTBuilder()
	server.Use(login.Ignore("/users/signup").
		Ignore("/users/login").LoginCheck())

	return server
}

func InitDB() *gorm.DB {
	db, err := gorm.Open(mysql.Open("root:root@tcp(127.0.0.1:13316)/webook"), &gorm.Config{})
	if err != nil {
		panic(err)
	}
	err = dao2.InitTables(db)
	if err != nil {
		panic(err)
	}

	return db
}

func InitUser(server *gin.Engine, db *gorm.DB) *web.UserHandler {
	dao := dao2.NewUserDao(db)
	repo := repostiory.NewUserRepostiory(dao)
	srv := service.NewUserService(repo)

	//注册用户相关路由
	u := web.NewUserHandler(srv)
	u.RegisterRoutes(server)

	return u
}
